Make pbump (internally) handle sizes bigger than MAX_INT. Fixes PR#33725 - thanks to Jonathan Wakely for the report git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@313031 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/fstream b/include/fstream index ffd5698..f57908c 100644 --- a/include/fstream +++ b/include/fstream 
@@ -315,7 +315,7 @@  else  this->setp((char_type*)__extbuf_,  (char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase())); - this->pbump(__rhs. pptr() - __rhs.pbase()); + this->__pbump(__rhs. pptr() - __rhs.pbase());  }  else if (__rhs.eback())  { @@ -434,7 +434,7 @@  ptrdiff_t __e = this->epptr() - this->pbase();  this->setp((char_type*)__extbuf_min_,  (char_type*)__extbuf_min_ + __e); - this->pbump(__n); + this->__pbump(__n);  }  if (__rhs.eback() == (char_type*)__extbuf_min_)  { @@ -450,7 +450,7 @@  ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();  __rhs.setp((char_type*)__rhs.__extbuf_min_,  (char_type*)__rhs.__extbuf_min_ + __e); - __rhs.pbump(__n); + __rhs.__pbump(__n);  }  }   @@ -724,7 +724,7 @@  if (__r == codecvt_base::partial)  {  this->setp(const_cast<char_type*>(__e), this->pptr()); - this->pbump(this->epptr() - this->pbase()); + this->__pbump(this->epptr() - this->pbase());  }  }  else 
diff --git a/include/locale b/include/locale index d30d950..a86645d 100644 --- a/include/locale +++ b/include/locale 
@@ -4110,7 +4110,7 @@  if (__r == codecvt_base::partial)  {  this->setp(const_cast<char_type *>(__e), this->pptr()); - this->pbump(this->epptr() - this->pbase()); + this->__pbump(this->epptr() - this->pbase());  }  }  else 
diff --git a/include/sstream b/include/sstream index fe65fd7..31cb37a 100644 --- a/include/sstream +++ b/include/sstream 
@@ -289,7 +289,7 @@  if (__bout != -1)  {  this->setp(__p + __bout, __p + __eout); - this->pbump(__nout); + this->__pbump(__nout);  }  __hm_ = __hm == -1 ? nullptr : __p + __hm;  __p = const_cast<char_type*>(__rhs.__str_.data()); @@ -332,7 +332,7 @@  if (__bout != -1)  {  this->setp(__p + __bout, __p + __eout); - this->pbump(__nout); + this->__pbump(__nout);  }  else  this->setp(nullptr, nullptr); @@ -403,7 +403,7 @@  if (__rbout != -1)  {  this->setp(__p + __rbout, __p + __reout); - this->pbump(__rnout); + this->__pbump(__rnout);  }  else  this->setp(nullptr, nullptr); @@ -416,7 +416,7 @@  if (__lbout != -1)  {  __rhs.setp(__p + __lbout, __p + __leout); - __rhs.pbump(__lnout); + __rhs.__pbump(__lnout);  }  else  __rhs.setp(nullptr, nullptr); @@ -471,7 +471,15 @@  this->setp(const_cast<char_type*>(__str_.data()),  const_cast<char_type*>(__str_.data()) + __str_.size());  if (__mode_ & (ios_base::app | ios_base::ate)) - this->pbump(__sz); + { + while (__sz > INT_MAX) + { +	this->pbump(INT_MAX); +	__sz -= INT_MAX; + } + if (__sz > 0) +	this->pbump(__sz); +	}  }  }   @@ -536,7 +544,7 @@  __str_.resize(__str_.capacity());  char_type* __p = const_cast<char_type*>(__str_.data());  this->setp(__p, __p + __str_.size()); - this->pbump(__nout); + this->__pbump(__nout);  __hm_ = this->pbase() + __hm;  #ifndef _LIBCPP_NO_EXCEPTIONS  } 
diff --git a/include/streambuf b/include/streambuf index f6182d6..ea64f57 100644 --- a/include/streambuf +++ b/include/streambuf 
@@ -255,6 +255,9 @@  inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY  void pbump(int __n) { __nout_ += __n; }   + _LIBCPP_ALWAYS_INLINE + void __pbump(streamsize __n) { __nout_ += __n; } +  inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY  void setp(char_type* __pbeg, char_type* __pend) {  __bout_ = __nout_ = __pbeg; 
diff --git a/src/strstream.cpp b/src/strstream.cpp index 01523cf..8b8521f 100644 --- a/src/strstream.cpp +++ b/src/strstream.cpp 
@@ -186,7 +186,7 @@  }  setg(buf, buf + ninp, buf + einp);  setp(buf + einp, buf + new_size); - pbump(static_cast<int>(nout)); + __pbump(nout);  __strmode_ |= __allocated;  }  *pptr() = static_cast<char>(__c); @@ -282,7 +282,7 @@  // min(pbase, newpos), newpos, epptr()  __off = epptr() - newpos;  setp(min(pbase(), newpos), epptr()); - pbump(static_cast<int>((epptr() - pbase()) - __off)); + __pbump((epptr() - pbase()) - __off);  }  __p = newoff;  } @@ -312,7 +312,7 @@  // min(pbase, newpos), newpos, epptr()  off_type temp = epptr() - newpos;  setp(min(pbase(), newpos), epptr()); - pbump(static_cast<int>((epptr() - pbase()) - temp)); + __pbump((epptr() - pbase()) - temp);  }  __p = newoff;  } 
diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.put.area/pbump2gig.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.put.area/pbump2gig.pass.cpp new file mode 100644 index 0000000..a581f88 --- /dev/null +++ b/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.put.area/pbump2gig.pass.cpp 
@@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <streambuf> + +// template <class charT, class traits = char_traits<charT> > +// class basic_streambuf; + +// void pbump(int n); + +#include <sstream> +#include <cassert> +#include "test_macros.h" + +struct SB : std::stringbuf +{ + SB() : std::stringbuf(std::ios::ate|std::ios::out) { } + const char* pubpbase() const { return pbase(); } + const char* pubpptr() const { return pptr(); } +}; + +int main() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + try { +#endif +	std::string str(2147483648, 'a'); +	SB sb; +	sb.str(str); +	assert(sb.pubpbase() <= sb.pubpptr()); +#ifndef TEST_HAS_NO_EXCEPTIONS +	} +	catch (const std::bad_alloc &) {} +#endif +}